#include "sharertos.h"
#include "stm32_common.h"


//中断控制及状态寄存器ICSR
#define		NVIC_INT_CTRL		*(volatile unsigned int*)0xE000ED04
//PENDSV 中断优先级控制寄存器
#define 	NVIC_SYSPRI14		*(volatile unsigned int*)0xE000ED22
//PENDSV 的优先级
#define     NVIC_PENDSV_PRI		0xFF
//为中断控制寄存器的bit28 位写1触发PENDSV中断
#define		NVIC_PENDSVSET		0x10000000


/**************************************
系统启动函数
**************************************/
void sharertos_startrun(void)
{
	//设置Pendsv的中断优先级最低
	NVIC_SYSPRI14 = NVIC_PENDSV_PRI;
	//设置psp寄存器0
	__asm__ __volatile__ ("MOVS R0, #0");
	__asm__ __volatile__ ("MSR  PSP,R0");
	//触发Pendsv中断
	NVIC_INT_CTRL = NVIC_PENDSVSET;
	//使能中断
	__asm__ __volatile__ ("CPSIE   I"); 
}

/**************************************
触发Pendsv中断,进行任务切换
***************************************/
void sharertos_triggerpendsv(void)
{
	//触发Pendsv中断
	NVIC_INT_CTRL = NVIC_PENDSVSET;
}


//Pendsv 中断
void PendSV_Handler(void)
{
__asm__ __volatile__( 
   "CPSID   I										\n"                                              
   "MRS     R0, PSP									\n"                                         
   "CBZ     R0, OS_CPU_PendSVHandler_nosave			\n"               
   "SUBS    R0, R0, #0x20							\n"                                   
   "STM     R0, {R4-R11}							\n"	
   "LDR     R1, =ostcbcurptr						\n"                                
   "LDR     R1, [R1]								\n"
   "STR     R0, [R1]								\n"                                      
                                                          
"OS_CPU_PendSVHandler_nosave:						\n"
    "LDR     R0,=oscurprio							\n"
    "LDR     R1,=oscurpriohight						\n"
    "LDRB    R2,[R1]								\n"
    "STRB    R2,[R0]								\n"

    "LDR     R0, =ostcbcurptr						\n"                             
    "LDR     R1, =ostcbhighrdyptr					\n"
    "LDR     R2, [R1]								\n"
    "STR     R2, [R0]								\n"

    "LDR     R0, [R2]								\n"
    "LDM     R0, {R4-R11}							\n"
    "ADDS    R0, R0, #0x20							\n"
    "MSR     PSP, R0								\n"
    "ORR     LR, LR, #0xF4							\n"
    "CPSIE   I										\n"
    "BX      LR										\n"
    "NOP"  
	);
}
